//
// This software is now distributed according to
// the Lesser Gnu Public License. Please see
// http://www.gnu.org/copyleft/lesser.txt for
// the details.
// -- Happy Computing!
//
package com.stevesoft.pat;

/**
 * This is just an integer that can have infinite value. It is used internally
 * to implement the *, and + parts of regular expressions.
 */
public class patInt {

	int i;
	boolean inf;

	/** Initialize to zero. */
	public patInt() {
		i = 0;
		inf = false;
	}

	/** Initialize to the value of init. */
	public patInt(int init) {
		i = init;
		inf = false;
	}

	/** Initialize to the value of p. */
	public patInt(patInt p) {
		i = p.i;
		inf = p.inf;
	}

	/** set this int to infinity. */
	public void setInf(boolean b) {
		inf = b;
		if (b)
			i = Integer.MAX_VALUE;
	}

	/** Increment the value of this by 1. */
	public final void inc() {
		if (!inf)
			i++;
	}

	/** Decrement the value of this by 1. */
	public final void dec() {
		if (!inf)
			i--;
	}

	/** Test to see if this is less than or equal to j. */
	public final boolean lessEq(patInt j) { /*
											 * if(inf) return false; if(j.inf)
											 * return true; return i <= j.i;
											 */
		return !inf && (j.inf || i <= j.i);
	}

	/** Test to see if two patterns are equal. */
	public final boolean equals(patInt j) {
		return !j.inf && !inf && i == j.i;
	}

	/**
	 * Formats the pattern as a String. Contrary to what you might expect,
	 * infinity is formatted as ""
	 */
	final public String toString() {
		if (inf)
			return "";
		else
			return "" + i;
	}

	/**
	 * This would be operator+=(patInt) if I were programming in C++.
	 */
	public final patInt pluseq(patInt p) {
		if (inf || p.inf)
			setInf(true);
		else
			i += p.i;
		return this;
	}

	/**
	 * Returns a patInt with value equal to the product of the value of p and
	 * this.
	 */
	public final patInt mul(patInt p) {
		if (inf || p.inf)
			return new patInf();
		return new patInt(i * p.i);
	}

	/**
	 * If the argument p has a smaller value than this, then set this Object
	 * equal to p.
	 */
	public final patInt mineq(patInt p) {
		if (p.inf)
			return this;
		if (inf)
			i = p.i;
		else if (p.i < i)
			i = p.i;
		setInf(false);
		return this;
	}

	/**
	 * If the argument p has a greater than this, then set this object equal to
	 * p.
	 */
	public final patInt maxeq(patInt p) {
		if (inf || p.inf) {
			setInf(true);
			return this;
		}
		if (p.i > i)
			i = p.i;
		return this;
	}

	/** Tests to see if this represents an infinite quantity. */
	public boolean finite() {
		return !inf;
	}

	/**
	 * Converts to a patInt to an int. Infinity is mapped Integer.MAX_VALUE;
	 */
	public int intValue() {
		return inf ? Integer.MAX_VALUE : i;
	}
};
